#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cwchar>
#include <locale>
#include <hpdf.h>
#include <ft2build.h>
#include FT_FREETYPE_H

// 定义页面宽度、高度、边距、每行字符数、每页字符数和字体大小
#define PAGE_WIDTH  600
#define PAGE_HEIGHT 740
#define PAGE_MARGIN 50
#define CHAR_PER_ROW 10
#define CHARS_PER_PAGE 200
#define FONT_SIZE 25

const char* font_path="/usr/share/fonts/dejavu/Arial Unicode MS.ttf";
FT_Library library;
FT_Face face;
FT_Error error;


void initFt()
{
    error = FT_Init_FreeType(&library);
    if (error) {
        std::cerr << "错误: 无法初始化FreeType库"<< std::endl;
        exit(1);
    }

    error = FT_New_Face(library, font_path, 0, &face);
    if (error == FT_Err_Unknown_File_Format) {
        std::cerr << "错误: 不支持的字体文件格式"<< std::endl;
        exit(1);
    } else if (error) {
        std::cerr << "错误: 无法打开字体文件"<< std::endl;
        exit(1);
    }
}
// 判断字符是否在有效范围内
bool isInRange(int code) {
    // //无效字符返回false
    // if (code >= 0x0000 && code < 0x0020) return false;
    // if (code >= 0x007F && code <= 0x009F) return false;
    // if (code >= 0xD800 && code <= 0xDFFF) return false;
    // if (code >= 0xE000 && code <= 0xF8FF) return false;
    // if (code >= 0x3400 && code < 0x4E00) return false;

    // return true;
    FT_UInt index=FT_Get_Char_Index(face, code);
    
    return index!=0;
}

int main() 
{
    HPDF_Doc pdf;
    HPDF_Page page;
    HPDF_Font font;
    HPDF_STATUS status;

    initFt();

    // 创建文档
    pdf = HPDF_New(NULL, NULL);
    if (!pdf) {
        std::cerr << "错误：无法创建PDF文档"<< std::endl;
        return 1;
    }

    // 添加页面
    page = HPDF_AddPage(pdf);
    if (!page) {
        std::cerr << "错误：无法添加新页面"<< std::endl;
        HPDF_Free(pdf);
        return 1;
    }

    // 设置页面大小
    HPDF_Page_SetWidth(page, PAGE_WIDTH);
    HPDF_Page_SetHeight(page, PAGE_HEIGHT);

    // 加载Arial Unicode MS字体
    HPDF_UseUTFEncodings(pdf); // 设置UTF-8编码
    const char* fontName = HPDF_LoadTTFontFromFile(pdf, font_path, HPDF_TRUE);
    font = HPDF_GetFont(pdf, fontName, "UTF-8"); // 设置UTF-8编码
    if (!font) {
        std::cerr << "错误：无法加载字体"<< std::endl;
        HPDF_Free(pdf);
        return 1;
    }

    // 为页面设置字体和字体大小
    HPDF_Page_SetFontAndSize(page, font, FONT_SIZE);

    std::setlocale(LC_ALL, ""); // 设置本地环境

    std::wstring wstr;
    for (unsigned int i = 0; i <= 65535; ++i) {  // Unicode范围
        if (!isInRange(i)) continue;
        wstr += static_cast<wchar_t>(i);
    }

    std::string cstr;
    cstr.resize(wstr.size() * 4 + 1);
    std::wcstombs(&cstr[0], wstr.c_str(), cstr.size());

    unsigned int total_chars = 0; // 每页计数,满了归零重新计数
    // Unicode范围0~65535
    for (unsigned int i = 0; i <= 65535; ++i) {  
        if (!isInRange(i)) continue;
        wchar_t wbuf[2] = { static_cast<wchar_t>(i), L'\0' };

        // 输出字符
        if (std::wcstombs(&cstr[0], wbuf, CHAR_PER_ROW + 1) == static_cast<size_t>(-1)) {
            std::cerr << "wcstombs"<< std::endl;
            return 1;
        }

        HPDF_Page_BeginText(page);
        HPDF_Page_TextOut(page, 80 + (total_chars % CHAR_PER_ROW) * (FONT_SIZE + 22),
            PAGE_HEIGHT - PAGE_MARGIN - (total_chars / CHAR_PER_ROW + 1) * (FONT_SIZE + 5),
            cstr.c_str());
        HPDF_Page_EndText(page);
        total_chars++;

        // 检查是否需要添加新页面
        if (total_chars >= CHARS_PER_PAGE) {
            // 添加新页面
            page = HPDF_AddPage(pdf);
            if (!page) {
                std::cerr << "错误：无法添加新页面"<< std::endl;
                HPDF_Free(pdf);
                return 1;
            }
            HPDF_Page_SetWidth(page, PAGE_WIDTH);
            HPDF_Page_SetHeight(page, PAGE_HEIGHT);
            HPDF_Page_SetFontAndSize(page, font, FONT_SIZE);
            total_chars = 0;
        }
    }

    // 将PDF保存到文件
    status = HPDF_SaveToFile(pdf, "output.pdf");
    if (status != HPDF_OK) {
        std::cerr << "错误：无法保存PDF文件"<< std::endl;
        HPDF_Free(pdf);
        return 1;
    }

    // 清理
    HPDF_Free(pdf);
    std::cout << "PDF创建成功"<< std::endl;

    return 0;
}